home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gigantic Games 2
/
Gigantic Games 2.iso
/
pc
/
_w_
/
wanderer
/
src
/
ami-curses.c
next >
Wrap
C/C++ Source or Header
|
1994-12-23
|
9KB
|
418 lines
/*
* A simple curses emulation for the Amiga, specifically for WANDERER
*
* Alan Bland
*/
#ifdef AMIGA
#include <stdio.h>
#include <ctype.h>
#include <curses.h>
#include <dos.h>
#include <intuition/intuition.h>
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <proto/exec.h>
#include <proto/intuition.h>
/* generated by Power Windows 2.0 */
#include "pw.palette.h"
#include "pw.menus.h"
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *S;
struct Window *W;
struct RastPort *R;
struct TextFont *map_font, *text_font;
struct Library *DiskfontBase;
#define TOPEDGE 12 /* how much of screen bar to show */
int WindowWidth = 640;
int WindowHeight = 200 - TOPEDGE;
int MouseX, MouseY;
/* getmouse - get current row and column of mouse */
getmouse(amr,amc)
int *amr;
int *amc;
{
*amr = MouseY / 8;
*amc = MouseX / 8;
}
/* Return when either a console key or mouse button is pressed. */
mouseorkey()
{
return nextevent(MOUSEBUTTONS | RAWKEY | MENUPICK, 1);
}
flushinput()
{
while (nextevent(RAWKEY, 0) >= 0) ;
}
/* returns next character, with special WANDERER translations */
getch()
{
return nextevent(RAWKEY | MENUPICK, 1);
}
/* returns next character with no special translations */
/* used mainly for getstr() */
getvanillach()
{
return nextevent(VANILLAKEY, 1);
}
cursor(state)
int state;
{
int x, y;
x = R->cp_x;
y = R->cp_y - R->Font->tf_Baseline;
SetDrMd(R, COMPLEMENT);
RectFill(R, x, y, x+8, y+R->Font->tf_YSize-1);
SetDrMd(R, JAM2);
}
/* special keymap for wanderer raw mode - translates function keys and
* cursor keys to wanderer single-key commands */
char mykeys[] = {
'`','1','2','3','4','5','6','7','8','9','0','-','=','\\',0,0,
'q','w','e','r','t','y','u','i','o','p','[',']',0,0,'j',0,
'a','s','d','f','g','h','j','k','l',';','\'',0,0,'h','@','l',
0,'z','x','c','v','b','n','m',',','.','/',0,0,0,'k',0,
' ','\b',0,'\n','\n','q',0,0,0,0,0,0,'k','j','l','h',
'~','#','@',0,0,'S','R',0,0,'!',0,0,0,0,0,'?',
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
char myshiftkeys[] = {
'~','!','@','#','$','%','^','&','*','(',')','_','+','|',0,0,
'Q','W','E','R','T','Y','U','I','O','P','{','}',0,0,0,0,
'A','S','D','F','G','H','J','K','L',':','"',0,0,0,0,0,
0,'Z','X','C','V','B','N','M','<','>','?',0,0,0,0,0,
' ','\b',0,'\n','\n',0,0,0,0,0,0,0,'k','j','l','h',
'~','#','@',0,0,'S','R',0,0,'!',0,0,0,0,0,'?',
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
nextevent(flags, wait)
long flags;
int wait;
{
register int class, code;
register struct IntuiMessage *message;
int result, qual;
/* show cursor if inputting a stream of text */
if (flags & VANILLAKEY) cursor(1);
ModifyIDCMP(W, CLOSEWINDOW | flags);
while (1)
{
if (wait)
{
/* get next event, waiting if none are available */
while ((message = (struct IntuiMessage *)GetMsg(W->UserPort)) == NULL)
{
Wait(1<<W->UserPort->mp_SigBit);
}
}
else
{
/* get next event, but return if none are available */
message = (struct IntuiMessage *)GetMsg(W->UserPort);
if (message == NULL)
{
result = -1;
break;
}
}
class = message->Class;
code = message->Code;
qual = message->Qualifier;
MouseX = message->MouseX;
MouseY = message->MouseY;
ReplyMsg((struct Message *)message);
switch (class)
{
case CLOSEWINDOW:
/* ignore for now */
continue;
case VANILLAKEY:
result = code;
if (result == '\r') result = '\n';
break;
case RAWKEY:
if (code&0x80) continue; /* ignore key releases */
/* only recognize wanderer keys */
/* can use cursor keys, hjkl, ibm keypad for moving */
if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
result = myshiftkeys[code];
else
result = mykeys[code];
if (result == 0) continue; /* ignore undef keys */
break;
case MENUPICK:
if (code == MENUNULL) continue;
switch (MENUNUM(code)) {
case 0:
switch (ITEMNUM(code)) {
case 0: result = 'W'; break;
case 1: result = 'S'; break;
case 2: result = 'R'; break;
case 4: result = 'c'; break;
case 5: result = 'q'; break;
default: continue;
}
break;
case 1:
switch (ITEMNUM(code)) {
case 0: result = '~'; break;
case 1: result = '#'; break;
case 2: result = '@'; break;
case 3: result = '!'; break;
case 4: result = '?'; break;
default: continue;
}
break;
default:
continue;
}
break;
case MOUSEBUTTONS:
switch (code)
{
case SELECTDOWN:
break; /* left button pressed */
default:
continue; /* ignore button releases */
}
result = MOUSE;
break;
default:
continue;
}
break;
}
/* turn off cursor if it was on */
if (flags & VANILLAKEY) cursor(0);
return result;
}
struct TextAttr font =
{
"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT
};
struct NewScreen ns =
{
0,0,640,200,4,BLACK,WHITE,HIRES,CUSTOMSCREEN,&font,"Wanderer V2.2",NULL,NULL
};
initscr()
{
struct NewWindow nw;
struct TextAttr font_attr;
if (S != NULL) return;
IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0);
if (IntuitionBase == NULL || GfxBase == NULL) exit(1);
/* load the digitized sound effects (yeah, what's it doing here?) */
initSounds();
/* load the map font */
DiskfontBase = (struct Library *) OpenLibrary("diskfont.library",0);
font_attr.ta_Name = "wanderer.font";
font_attr.ta_YSize = 8;
font_attr.ta_Style = 0;
font_attr.ta_Flags = 0;
map_font = (struct TextFont *) OpenDiskFont(&font_attr);
if ((S = (struct Screen *) OpenScreen(&ns)) == NULL) exit(1);
nw.LeftEdge = 0;
nw.TopEdge = TOPEDGE;
nw.Width = WindowWidth;
nw.Height = WindowHeight;
nw.DetailPen = BLACK;
nw.BlockPen = WHITE;
nw.Title = NULL;
nw.Flags = SMART_REFRESH | ACTIVATE | BACKDROP |
BORDERLESS | NOCAREREFRESH;
nw.IDCMPFlags = RAWKEY;
nw.Type = CUSTOMSCREEN;
nw.FirstGadget = NULL;
nw.CheckMark = NULL;
nw.Screen = S;
nw.BitMap = NULL;
if ((W = (struct Window *) OpenWindow(&nw)) == NULL) exit(1);
R = W->RPort;
/* setup colors */
LoadRGB4(&S->ViewPort, Palette, PaletteColorCount);
/* keep track of original font */
text_font = R->Font;
SetAPen(R, TEXT_COLOR);
SetBPen(R, BACK_COLOR);
ShowTitle(S, FALSE);
SetMenuStrip(W, &MenuList1);
clear();
}
move(r,c)
int r,c;
{
Move(R, c*8, r*8 + R->Font->tf_Baseline);
}
eraseeol()
{
int x, y;
x = R->cp_x;
y = R->cp_y - R->Font->tf_Baseline;
SetAPen(R, BACK_COLOR);
RectFill(R, x, y, WindowWidth, y+R->Font->tf_YSize-1);
SetAPen(R, TEXT_COLOR);
}
eraserow(r)
{
move(r,0);
eraseeol();
}
endwin()
{
freeSounds(NULL);
if (map_font) CloseFont(map_font);
if (W) { ClearMenuStrip(W); CloseWindow(W); }
if (S) CloseScreen(S);
}
set_map_font(flag)
int flag;
{
if (flag) SetFont(R, map_font);
else SetFont(R, text_font);
}
clear()
{
SetAPen(R, BACK_COLOR);
RectFill(R, 0, 0, WindowWidth, WindowHeight);
SetAPen(R, TEXT_COLOR);
move(0,0);
}
/* get a line of input from the console, handling backspaces */
/* menus are disable while inputting */
getstr(s)
char *s;
{
char *origs = s;
int c;
ClearMenuStrip(W);
SetAPen(R, INPUT_COLOR);
while ( (c=getvanillach()) != '\n' && c!='\r' && c!= EOF ) {
if ( c == '\b' ) {
if ( s > origs ) {
addstr("\b \b");
s--;
}
}
else if (c == 24) {
while (s > origs) {
addstr("\b \b");
s--;
}
} else if (isprint(c)) {
addch(c);
*s++ = c;
}
refresh();
}
*s = '\0';
SetAPen(R, TEXT_COLOR);
SetMenuStrip(W, &MenuList1);
}
addstr(s)
char *s;
{
/* output is fastest if is many chars as possible can be */
/* displayed in a single Text() call, so we scan for special */
/* characters that need to be interpreted, and do the rest */
/* in as few Text() calls as possible */
register int i,a;
for (i=0,a=0; ; ++i) {
if (s[i] < ' ') {
/* special character found */
/* output everything up to this character */
if (i-a>0) Text(R, s+a, i-a);
/* interpret the special character */
if (s[i] == 0) break;
addch(s[i]);
/* continue after the special character */
a = i+1;
}
}
}
addch(c)
int c;
{
char s;
switch (c) {
case '\n':
Move(R, 0, R->cp_y + 8);
break;
case '\r':
Move(R, 0, R->cp_y);
break;
case '\t':
Move(R, R->cp_x + 64 - (R->cp_x % 64), R->cp_y);
break;
case '\b':
Move(R, R->cp_x - 8, R->cp_y);
break;
case '\007':
DisplayBeep(S);
break;
default:
s = c;
Text(R, &s, 1);
break;
}
}
struct IntuiText fataltext = { 1,0,COMPLEMENT,16,32,NULL,NULL,NULL };
struct IntuiText canceltext = { 1,0,COMPLEMENT,2,2,NULL,"goodbye",NULL };
fatal(text)
char *text;
{
fataltext.IText = text;
AutoRequest(W, &fataltext, NULL, &canceltext, 0, 0, 320, 90);
endwin();
exit(1);
}
#endif